Matrix product operators


Dense matrix product operators

There are 3 classes in this module: MPOSite, DenseMPO, DenseMPOList

DenseMPO

This is the standard textbook-like MPO that acts on specified sites (DenseMPO.sites). It is a list of MPOSite-s

 | | | |
-O-O-O-O-
 | | | |

MPOSite

Each tensor in the DenseMPO is stored as MPOSite. For example, a 4-body DenseMPO is going to be a list of 4 MPOSite-s.

 |
-O-
 |

DenseMPOList

A list of DenseMPO-s. Here, the DenseMPOList is usually used to represent Hamiltonians. Hamiltonians are special because they are normally a sum of polynomially-many tensor product operator (TPO) terms. For local hamiltonians, each TPO acts on a finite number of sites. Hence we can store a Hamiltonian as a list of TPO terms, where each TPO is represented as a DenseMPO. For example, the Ising model contains nearest-neighbour \(\sigma_x\sigma_x\) and \(\sigma_z\) terms, and every 2-body TPO term \(\sigma_x\sigma_x\) and local term \(\sigma_z\) would be stored as a separate DenseMPO added to a DenseMPOList.

 | |       | |       |
-O-O-  ,  -O-O-  ,  -O-  ,  ...
 | |       | |       |

Therefore, the number of sites in each individual DenseMPO in a DenseMPOList does not correspond to the total number of sites - instead, it corresponds to the number of sites on which the individual Hamiltonian term is acting on.

Some useful attributes/functions

Initialize MPOSite with MPOSite([list of sites], tensor_str_name, pstrength=None, prefactor=1.0, operators=op_dict, params={})

  • MPOSite.site = on which site in a system does this MPO site act

  • MPOSite.operator = get an actual tensor

  • MPOSite.pstrength, MPOSite.weight = prefactors that multiply the elements of an operator.

The difference between pstrength and weight is that pstrength is parametrized via params dictionary and weight is a number. The default prefactor is 1, i.e. pstrength=None and weight=1.

Initialize DenseMPO with DenseMPO([list of MPOSite-s], tensor_backend)

  • DenseMPO.num_sites = on how many sites does this MPO act

  • DenseMPO.sites = list of sites on which MPO acts

  • DenseMPO[ind].operator = get tensor on site ind

  • DenseMPO.append(MPOSite) = add MPOSite to DenseMPO

Initialize DenseMPOList with DenseMPOList() and then append DenseMPO-s

  • DenseMPOList[ind] = get ind-th DenseMPO in a list

  • DenseMPOList.from_model_prepared(\*args, \*\*kwargs) = create a DenseMPOList object from a given Hamiltonian model

See the more detailed documentation of individual functions below


Indexed tensor product operators

This is the default MPO representation for the Hamiltonians and the observables which the library uses during computationally extensive operations in simulations. (The other option are sparse MPOs, but indexed tensor product operators (iTPOs) for now allow more generality.) Here is the short introduction to iTPO framework.

A Hamiltonian MPO (or any MPO operator) is often a sum of tensor product terms (TPOs), where every TPO term contains n operators acting on n sites. Therefore, as it is the case with dense MPOs (see above), we can treat the Hamiltonian as a list of TPO terms.

Very often, however, we have only few different operator tensors building the Hamiltonian: the Ising Hamiltonian is, for example, built only from \(\sigma_x\) and \(\sigma_z\) operators. Therefore, to save memory, we don’t have to define our Hamiltonian MPO by saving every operator at every site (as it is done in a DenseMPOList), but instead we can assign every operator tensor an index ii and store only the information of type: “operator ii acting on site x with the prefactor w”, where ii points to e.g. \(\sigma_x\) tensor. Every TPO term is assigned a unique integer TPO ID going from 0 to number of TPO terms. The same TPO IDs are assigned to the corresponding operators inside TPO terms, so we can keep track which operator belongs to which TPO term. This way of representing MPOs is what we call the indexed TPO picture.

Another difference between iTPOs with respect to DenseMPO / DenseMPOLists is that local terms are treated differently in the iTPO picture. All the local terms acting on the same site are contracted into a single local term of same dimensions.

There are 3 classes in this module: ITPOTerm, ITPOSites, ITPO

ITPOTerm

ITPOTerm contains all operators acting on a single site, each coming from a different TPO term in the MPO. The “Term” in the name is a bit misleading, as ITPOTerm does not refer to the TPO term (which usually acts on more than one site), but instead refers to a collection of operators acting on a single site. ITPOTerm can contain one local term, which is treated separately and is stored under ITPOTerm._local.

ITPO

The full MPO, containing all its TPO terms. In general, it has two parts: ITPO.site_terms and ITPO.eff_ops. ITPO.site_terms are an instance of ITPOSites (description below) and they represent the TPO terms coming from a Hamiltonian or any operator acting on the physical sites of the tensor network. ITPO.eff_ops, on the other hand, represent all the TPO terms inside the effective operators around each tensor in a tensor network. Therefore, ITPO.eff_ops depend on a TN ansatz. In a simulation, ITPO.site_terms are usually the input Hamiltonian and ITPO.eff_ops are computed by contracting this Hamiltonian with tensors in a TN.

ITPOSites

Represent the TPO terms coming from a Hamiltonian or any operator acting on physical sites of the tensor network. Stored as a list of ITPOTerm-s, such that there is one ITPOTerm per system site.

Some useful attributes/functions/remarks

ITPOTerm acts on a single site, but there is no attribute inside of it which tell which site it is. This info is instead stored in ITPO and ITPOSites.

  • ITPOTerm._tensors : following the iTPO convention, this is a dictionary with all the tensors, where the key is the operator string which defines it and the value is a corresponding tensor

  • ITPOTerm._operators : a dictionary, with the key being a TPO ID of the corresponding TPO term in the parent ITPO and the value is the corresponding operator string

  • ITPOTerm.weights : list of prefactors for every operator tensor in ITPOTerm, ordered by TPO IDs

  • ITPOTerm._local : tensor of a local term, if any

The easiest way to create an ITPO is to first create a DenseMPOList, initialize the empty ITPO with itpo = ITPO(num_sites), and then convert DenseMPOList to ITPO with itpo.add_dense_mpo_list(DenseMPOList)

  • ITPO.site_terms : ITPOSites, i.e. a list of ITPOTerm-s that act on physical sites in a TN

  • ITPO.eff_ops : a dictionary of effective operators around every tensor in a tensor network. The keys in a dictionary specify which tensor we are looking at, with the convention differing for different TNs (e.g. for MPS, it’s just the index of the tensor, for TTN it’s (layer_idx, tensor_idx)). The value for each iterm in ITPO.eff_ops is again a dictionary containing three ITPOTerm-s, as there are three effective operators per tensor. The convention for keys of this dictionary again differs for different TNs, but (roughly speaking) it’s supposed to specify whether the corresponding ITPOTerm is left, down, or right effective operator. Upon initialization, ITPO.eff_ops is an empty dictionary. The actual effective operators are computed once ITPO.contr_to_eff_op() is called.

See the more detailed documentation of individual functions below


Sparse matrix operators


Sparse matrix product operators


Abstract effective operators


Disentanglers


TTN Projector